﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using FinApp.Utils.Camera;
using com.google.zxing.qrcode;
using Microsoft.Devices;
using System.Windows.Navigation;
using com.google.zxing.common;
using com.google.zxing;
using System.Runtime.Serialization.Json;
using FinApp.Model;
using FinApp.Utils.Streams;
using FinApp.DataProviders;
using FinApp.DataProviders.Configuration;
using System.Globalization;

namespace FinApp.Views {
    public partial class QRReaderPage : PhoneApplicationPage {

        #region Members
        private readonly DispatcherTimer _timer;
        private readonly ObservableCollection<string> _matches;
        private PhotoCameraLuminanceSource _luminance;
        private QRCodeReader _reader;
        private PhotoCamera _photoCamera; 
        #endregion

        #region Constructors
        public QRReaderPage() {
            InitializeComponent();

            _matches = new ObservableCollection<string>();
            _matchesList.ItemsSource = _matches;

            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMilliseconds(250);
            _timer.Tick += (o, arg) => ScanPreviewBuffer();
        } 
        #endregion

        protected override void OnNavigatedTo(NavigationEventArgs e) {
            _photoCamera = new PhotoCamera();
            _photoCamera.Initialized += OnPhotoCameraInitialized;
            _previewVideo.SetSource(_photoCamera);

            CameraButtons.ShutterKeyHalfPressed += (o, arg) => _photoCamera.Focus();

            base.OnNavigatedTo(e);
        }

        private void OnPhotoCameraInitialized(object sender, CameraOperationCompletedEventArgs e) {
            int width = Convert.ToInt32(_photoCamera.PreviewResolution.Width);
            int height = Convert.ToInt32(_photoCamera.PreviewResolution.Height);

            _luminance = new PhotoCameraLuminanceSource(width, height);
            _reader = new QRCodeReader();

            Dispatcher.BeginInvoke(() => {
                _previewTransform.Rotation = _photoCamera.Orientation;
                _timer.Start();
            });
        }

        private void ScanPreviewBuffer() {
            try {
                _photoCamera.GetPreviewBufferY(_luminance.PreviewBufferY);
                var binarizer = new HybridBinarizer(_luminance);
                var binBitmap = new BinaryBitmap(binarizer);
                var result = _reader.decode(binBitmap);
                Dispatcher.BeginInvoke(() => DisplayResult(result.Text));
            } catch {

            }
        }


        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(PaymentModel));
        PaymentModel payment;

        private void DisplayResult(string text) {
            if (text.StartsWith("{")) {
                try {
                    this.payment = (PaymentModel)serializer.ReadObject(text.ToStream());
                    ChryptoKeyProvider.Instance.CryptoKeyCompleted += new DataProviders.EventArguments.CryptoKeyCompletedEventHandler(OnCryptoKeyCompleted);
                    ChryptoKeyProvider.Instance.GetCommerceAccountEncryptionKeysAsync(payment.CommerceId);
                } catch {
                    if (MessageBox.Show("Se ha detectado un código QR que no es un pago. ¿Desea Continuar?", "Código no válido", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel) {
                        NavigationService.GoBack();
                    }
                }
                //{ "checkField": "9ZDzYlDYsryZqmvRdxaRfODOclChnVcvD241jTnnwhU=", "quantity": 18.0, "currency": "EURO", "commerceId": "508b1a1de4b04a375aa94c4c" }
            } else {
                if (MessageBox.Show("Se ha detectado un código QR que no es un pago. ¿Desea Continuar?", "Código no válido", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel) {
                    NavigationService.GoBack();
                }
            }
            //if (!_matches.Contains(text))
            //    _matches.Add(text);
        }

        private void OnCryptoKeyCompleted(object sender, DataProviders.EventArguments.ChryptoKeyEventArgs e) {
            if (e.LoginStatus == DataProviders.Enumerations.ProviderResponseEnumeration.OK) {
                if (this.payment.CommerceId == ChryptoProvider.Instance.DecryptString(this.payment.CheckField, e.CommercePasswordKey, e.CommerceSaltKey)) {

                    /// Redirección a seleccionar tarjeta para pago
                    NavigationService.Navigate(new Uri(string.Format("/Views/CreditCardSelectorPage.xaml?CommerceId={0}&Quantity={1}&CheckField={2}&Password={3}&Salt={4}", Uri.EscapeDataString(this.payment.CommerceId), Uri.EscapeDataString(this.payment.Quantity.ToString(CultureInfo.InvariantCulture)), Uri.EscapeDataString(this.payment.CheckField), Uri.EscapeDataString(e.CommercePasswordKey), Uri.EscapeDataString(e.CommerceSaltKey)), UriKind.Relative));
                } else {
                    MessageBox.Show("La entidad generadora del tiquet no es válida. No se puede seguir con la operación", "Operación no válida", MessageBoxButton.OK);
                    NavigationService.GoBack();
                }
            } else { /// Si se produce un error en el servidor, lo mostramos
                MessageBox.Show(e.Message);
                NavigationService.GoBack();
            }
        }

    }
}